/**
 * @Question.Title: 划分为k个相等的子集
 * @Question.No: 698
 * @Author: DQ
 * @Date: 2021-04-15 14:51:36
 * @Description: 
 */
//给定一个整数数组 nums 和一个正整数 k，找出是否有可能把这个数组分成 k 个非空子集，其总和都相等。 
//
// 示例 1： 
//
// 输入： nums = [4, 3, 2, 3, 5, 2, 1], k = 4
//输出： True
//说明： 有可能将其分成 4 个子集（5），（1,4），（2,3），（2,3）等于总和。 
//
// 
//
// 提示： 
//
// 
// 1 <= k <= len(nums) <= 16 
// 0 < nums[i] < 10000 
// 
// Related Topics 递归 动态规划 
// 👍 342 👎 0

package dq.leetcode.editor.cn;

import java.util.Arrays;

public class PartitionToKEqualSumSubsets {
    public static void main(String[] args) {
        Solution solution = new PartitionToKEqualSumSubsets().new Solution();
        int[] nums = {4, 3, 2, 3, 5, 2, 1};
        int k = 4;
        System.out.println(solution.canPartitionKSubsets(nums, k));
    }
        //leetcode submit region begin(Prohibit modification and deletion)
class Solution {
    public boolean canPartitionKSubsets(int[] nums, int k) {
        this.ave = Arrays.stream(nums).sum() / k;
        Arrays.sort(nums);
        this.nums = nums;
        this.k = k;
        this.visit = new boolean[nums.length];
        for(int i = 0; i < nums.length; i++){
            dfs(i,0);
        }

        return this.k==0;
    }
    int k;
    int ave ;
    int[] nums;
    boolean[] visit;
    public boolean dfs(int i, int pre){
        if(i >= nums.length) return false;
        if(visit[i]) return false;
        //要

        if(pre + nums[i] > ave) {
            return false;
        }
        else if(pre + nums[i] == ave){
            visit[i] = true;
            k--;
            return true;
        }else{

            visit[i] = true;
            if(!dfs(i+1, pre)) {
                visit[i] = false;
                return false;
            }
            return true;

        }
    }

}
//leetcode submit region end(Prohibit modification and deletion)

}